/**
 * @file 碰撞检测
 * @description 处理碰撞检测和资源清理
 * @author 郑宇翔
 * @date 2025-03-21
 * @lastEditors 郑宇翔
 * @lastEditTime 2025-03-23
 */

import * as THREE from 'three'
import { ConvexObjectBreaker } from 'three/addons/misc/ConvexObjectBreaker.js';
import { scene } from './scene'
import type Ammo from 'ammojs-typed'
import { drillBit } from './drill'
import { model } from './loader';
import { message, notification } from 'ant-design-vue';
import '@/assets/notification.css';
import type { Ref } from 'vue';
import { curveTrajectory } from './pipe'
import { isDrilling } from './perspectiveSwitching'
import { useCollisionWarningStore } from '@/store/collisionWarning'

// 创建音频对象
export const fragmentationSound = new Audio(new URL('@/assets/sound/fragmentation.mp3', import.meta.url).href);

// 加载障碍物纹理
const textureLoader = new THREE.TextureLoader();
export const obstacleTexture = textureLoader.load(new URL('@/assets/textures/obstacle.jpg', import.meta.url).href);
obstacleTexture.wrapS = THREE.RepeatWrapping;
obstacleTexture.wrapT = THREE.RepeatWrapping;
obstacleTexture.repeat.set(2, 2);

// 物理相关变量
const gravityConstant = 9.8; // 重力常量
/**
 * 调度器
 */
let dispatcher: Ammo.btCollisionDispatcher;
/**
 * 碰撞配置
 */
let collisionConfiguration: Ammo.btCollisionConfiguration;
/**
 * 宽相检测
 */
let broadphase: Ammo.btBroadphaseInterface;
/**
 * 约束求解器
 */
let solver: Ammo.btConstraintSolver;
/**
 * 物理世界
 */
export let physicsWorld: Ammo.btDiscreteDynamicsWorld;
/**
 * 碰撞边
 */
const margin = 0.05;
/**
 * 凸多面体破碎器
 */
const convexBreaker = new ConvexObjectBreaker();

/**
 * 刚体包含所有可移动物体
 */
export const rigidBodies: THREE.Mesh[] = [];

const pos = new THREE.Vector3(); // 位置向量
const quat = new THREE.Quaternion(); // 四元数，用于表示旋转
let transformAux1: Ammo.btTransform; // 辅助变换对象
let tempBtVec3_1: Ammo.btVector3; // 辅助向量

// 用于存储要移除的对象
const objectsToRemove: (THREE.Mesh | null)[] = new Array(500).fill(null);

// 用于存储要移除的对象的数量
let numObjectsToRemove = 0;

// 碰撞点和法线
const impactPoint = new THREE.Vector3();
const impactNormal = new THREE.Vector3();



let AmmoLib: any;
export { AmmoLib };

/**
 * 钻头的物理对象
 */
export let drillBitPhysicsBody: Ammo.btRigidBody | null = null;



// 添加圆柱体相关变量
const CYLINDER_RADIUS = 0.6; // 圆柱体半径
const CYLINDER_HEIGHT = 3;   // 圆柱体高度
const CYLINDER_SEGMENTS = 32; // 圆柱体分段数
const CYLINDER_MASS = 50;    // 圆柱体质量

/**
 * 轨道上的障碍物数组
 */
const trajectoryObstacles: THREE.Mesh[] = [];

/**
 * 渐隐持续时间（毫秒）
 */
const FADE_DURATION = 2000;

/**
 * 碎片信息接口
 * @interface DebrisInfo
 * @property {THREE.Mesh} mesh - 碎片网格对象
 * @property {number} creationTime - 创建时间戳
 * @property {THREE.Material | THREE.Material[]} material - 碎片材质
 * @property {number} originalOpacity - 原始不透明度
 */
interface DebrisInfo {
    mesh: THREE.Mesh;
    creationTime: number;
    material: THREE.Material | THREE.Material[];
    originalOpacity: number;
}

/**
 * 活动碎片数组
 * @type {DebrisInfo[]}
 */
const activeDebris: DebrisInfo[] = [];

// 添加下放度调整相关变量
let originalSpeed = 0;
let isSpeedReduced = false;
let speedRecoveryTimeout: number | null = null;
const SPEED_REDUCTION_FACTOR = 0.3; // 速度降低到原来的30%
const SPEED_RECOVERY_DELAY = 5000; // 5秒后恢复速度

// 添加上提速度相关变量
let originalPullUpSpeed = 0;
let isPullUpSpeedReduced = false;
let pullUpSpeedRecoveryTimeout: number | null = null;
const PULLUP_SPEED_REDUCTION_FACTOR = 0.4; // 上提速度降低到原来的40%
const PULLUP_SPEED_RECOVERY_DELAY = 4000; // 4秒后恢复速度

/**
 * 上一次速度方向
 */
let previousSpeedSign = 0;

// 修改WIREFRAME_MODE为变量而不是常量
/**
 * 是否显示线框模式（开发调试用）
 */
let WIREFRAME_MODE = true;

/**
 * 线框材质
 */
const wireMaterial = new THREE.MeshBasicMaterial({
    color: 0x00ff00,
    wireframe: true,
    transparent: true,
    opacity: 0.6
});

// 记录上一次添加碰撞点的时间
let lastCollisionRecordTime = 0;

// 等待 Ammo.js 加载完成
// 初始化Ammo物理引擎
export async function initCollision() {
    try {
        console.log('开始加载 Ammo.js...');

        // 加载 Ammo 物理引擎库
        AmmoLib = await loadAmmo();

        console.log('Ammo 加载完成，初始化物理引擎...');

        // 确认关键构造函数存在
        if (!AmmoLib.btDefaultCollisionConfiguration) {
            throw new Error('AmmoLib.btDefaultCollisionConfiguration 不存在');
        }

        // 初始化物理引擎并创建场景物体
        await initPhysics();
        console.log('物理引擎初始化完成，开始创建物体...');
        createObjects();
        console.log('场景物体创建完成');

    } catch (error) {
        console.error('Ammo.js 加载或初始化失败:', error);
        // 显示用户友好的错误消息
        notification.error({
            message: '物理引擎加载失败',
            description: '无法初始化物理引擎，部分功能可能不可用。请刷新页面重试。',
            duration: 0 // 不自动关闭
        });
    }
}

/**
 * 加载 Ammo.js 物理引擎
 * @returns {Promise<any>} 加载完成的 Ammo 实例
 */
async function loadAmmo(): Promise<any> {
    // 首先检查全局 Ammo 是否已存在
    if (typeof (window as any).Ammo === 'function') {
        console.log('全局 Ammo 已存在，直接使用');
        return (window as any).Ammo();
    }

    console.log('尝试加载 Ammo.js...');

    // 创建加载 Promise
    return new Promise<any>((resolve, reject) => {
        const script = document.createElement('script');
        script.src = './ammojs-typed/ammo/ammo.js';
        script.async = true;// 表示脚本使用异步加载，不会阻塞页面渲染

        script.onload = () => {
            if (typeof (window as any).Ammo === 'function') {
                console.log('Ammo.js 加载成功！');
                resolve((window as any).Ammo());
            } else {
                reject(new Error('加载 Ammo 失败：Ammo 不是函数'));
            }
        };

        script.onerror = () => {
            reject(new Error('加载 Ammo 失败'));
        };
        
        document.body.appendChild(script);
    });
}

/**
 * 初始化物理世界及相关组件
 * @description 创建物理世界并配置重力等参数
 */
async function initPhysics() {
    // 创建默认碰撞配置
    collisionConfiguration = new AmmoLib.btDefaultCollisionConfiguration();

    // 创建碰撞调度器
    dispatcher = new AmmoLib.btCollisionDispatcher(collisionConfiguration);

    // 创建宽相碰撞检测算法
    broadphase = new AmmoLib.btDbvtBroadphase();

    // 创建顺序脉冲约束求解器
    solver = new AmmoLib.btSequentialImpulseConstraintSolver();

    // 创建离散动力学世界
    physicsWorld = new AmmoLib.btDiscreteDynamicsWorld(
        dispatcher,
        broadphase,
        solver,
        collisionConfiguration
    );

    // 设置世界重力
    physicsWorld.setGravity(new AmmoLib.btVector3(0, -gravityConstant, 0));

    // 创建辅助变换和向量对象
    transformAux1 = new AmmoLib.btTransform();
    tempBtVec3_1 = new AmmoLib.btVector3(0, 0, 0);
}

/**
 * 创建可破碎物体
 * @param mass 质量
 * @param halfExtents 半径
 * @param pos 位置
 * @param quat 四元数
 * @param material 材质
 * @param isCylinder 是否为圆柱体
 */
function createObject(mass: number, halfExtents: THREE.Vector3, pos: THREE.Vector3, quat: THREE.Quaternion, material: THREE.Material, isCylinder: boolean = false) {
    let geometry;
    if (isCylinder) {
        // 增加圆柱体的分段数以提高碰撞精度
        geometry = new THREE.CylinderGeometry(halfExtents.x, halfExtents.x, halfExtents.y * 2, 32, 32);
    } else {
        geometry = new THREE.BoxGeometry(halfExtents.x * 2, halfExtents.y * 2, halfExtents.z * 2);
    }

    // 在开发模式下使用线框材质
    const displayMaterial = WIREFRAME_MODE ? wireMaterial : material;
    const object = new THREE.Mesh(geometry, displayMaterial);

    // 如果是线框模式，保存原始材质
    if (WIREFRAME_MODE) {
        object.userData.originalMaterial = material;
    }

    object.position.copy(pos);
    object.quaternion.copy(quat);

    // 降低物体的质量以使其更容易破碎
    const adjustedMass = isCylinder ? mass * 0.5 : mass;

    // 设置物体为可破碎，并增加破碎参数
    convexBreaker.prepareBreakableObject(object, adjustedMass, new THREE.Vector3(), new THREE.Vector3(), true);

    // 为圆柱体设置特殊的物理属性
    if (isCylinder) {
        object.userData.cylinderCollision = true; // 标记为圆柱体
        object.userData.breakabilityFactor = 1.5; // 增加破碎系数
    }

    createDebrisFromBreakableObject(object);
}

// 清除轨道上的障碍物
function clearTrajectoryObstacles() {
    trajectoryObstacles.forEach(obstacle => {
        if (obstacle.userData.physicsBody) {
            physicsWorld.removeRigidBody(obstacle.userData.physicsBody);
        }
        scene.remove(obstacle);
        const index = rigidBodies.indexOf(obstacle);
        if (index !== -1) {
            rigidBodies.splice(index, 1);
        }

        // 释放材质
        if (obstacle.material instanceof THREE.Material) {
            if (obstacle.material instanceof THREE.MeshStandardMaterial || obstacle.material instanceof THREE.MeshPhongMaterial) {
                if (obstacle.material.map) obstacle.material.map.dispose();
            }
            obstacle.material.dispose();
        }
    });
    trajectoryObstacles.length = 0;
}

// 创建轨道上的圆柱体
function createTrajectoryObstacles() {
    if (!model) return;

    // 清除现有的障碍物
    clearTrajectoryObstacles();

    // 使用带纹理的材质
    const cylinderMaterial = new THREE.MeshStandardMaterial({
        map: obstacleTexture,
        metalness: 0.1,
        roughness: 1,
        color: 0x808080 // 使用棕灰色
    });

    // 在当前轨迹上创建障碍物
    const points = curveTrajectory.getPoints(15); // 获取轨迹上的15个点
    points.forEach((point, index) => {
        // 跳过前几个点和最后几个点，避免在起始和结束位置创建障碍物
        if (index < 3 || index > points.length - 4 || point.y > 0) return;

        // 每隔几个点创建一个圆柱体
        if (index % 3 === 0) {
            const cylinderGeometry = new THREE.CylinderGeometry(
                CYLINDER_RADIUS, CYLINDER_RADIUS, CYLINDER_HEIGHT, CYLINDER_SEGMENTS
            );

            // 在开发模式下使用线框材质
            const displayMaterial = WIREFRAME_MODE ? wireMaterial : cylinderMaterial;
            const cylinder = new THREE.Mesh(cylinderGeometry, displayMaterial);

            // 如果是线框模式，保存原始材质
            if (WIREFRAME_MODE) {
                cylinder.userData.originalMaterial = cylinderMaterial;
            }

            // 设置圆柱体位置
            cylinder.position.copy(point);

            // 计算圆柱体朝向
            if (index < points.length - 1) {
                const direction = new THREE.Vector3().subVectors(points[index + 1], point).normalize();
                const quaternion = new THREE.Quaternion();
                quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), direction);
                cylinder.quaternion.copy(quaternion);
            }

            // 设置为可破碎物体
            convexBreaker.prepareBreakableObject(cylinder, CYLINDER_MASS, new THREE.Vector3(), new THREE.Vector3(), true);
            cylinder.userData.cylinderCollision = true;

            // 创建物理特性
            createDebrisFromBreakableObject(cylinder);

            // 禁用重力
            const physicsBody = cylinder.userData.physicsBody;
            if (physicsBody) {
                physicsBody.setGravity(new AmmoLib.btVector3(0, 0, 0));
                // 设置为静态物体，直到碰撞
                physicsBody.setActivationState(4);
            }

            // 将障碍物添加到数组中
            trajectoryObstacles.push(cylinder);
        }
    });
}

// 创建场景中的物体
function createObjects() {
    if (!model) return;
    // 遍历模型中所有以ground开头的物体，添加物理特性
    model.traverse((object) => {
        if (object.name.startsWith('ground') && object instanceof THREE.Mesh) {
            // 隐藏地面物体
            object.visible = false;

            const box = new THREE.Box3().setFromObject(object); // 获取地面物体的包围盒
            const size = box.getSize(new THREE.Vector3()); // 获取包围盒的尺寸
            const center = box.getCenter(new THREE.Vector3()); // 获取包围盒的中心

            // 创建地面物理对象
            const groundShape = new AmmoLib.btBoxShape(new AmmoLib.btVector3(size.x * 0.5, size.y * 0.5, size.z * 0.5));
            groundShape.setMargin(margin);

            const groundTransform = new AmmoLib.btTransform();
            groundTransform.setIdentity(); // 设置为单位变换
            groundTransform.setOrigin(new AmmoLib.btVector3(center.x, center.y, center.z)); // 设置位置

            const groundMass = 0; // 质量为0，使其成为静态物体
            const groundLocalInertia = new AmmoLib.btVector3(0, 0, 0); // 静态物体不需要惯性
            const groundMotionState = new AmmoLib.btDefaultMotionState(groundTransform);
            const groundRbInfo = new AmmoLib.btRigidBodyConstructionInfo(groundMass, groundMotionState, groundShape, groundLocalInertia);
            const groundBody = new AmmoLib.btRigidBody(groundRbInfo);

            groundBody.setFriction(0.5); // 设置摩擦系数
            physicsWorld.addRigidBody(groundBody); // 将地面刚体添加到物理世界
        }
        // 添加barrier物体的物理特性
        if (object.name.startsWith('barrier') && object instanceof THREE.Mesh) {
            object.visible = false;
            const box = new THREE.Box3().setFromObject(object);
            const size = box.getSize(new THREE.Vector3());
            const center = box.getCenter(new THREE.Vector3());

            // 创建barrier的物理对象
            const barrierMass = 100; // 设置适当的质量
            const barrierHalfExtents = new THREE.Vector3(size.x * 0.5, size.y * 0.5, size.z * 0.5);
            pos.copy(center);
            quat.set(0, 0, 0, 1);


            createObject(barrierMass, barrierHalfExtents, pos, quat, Array.isArray(object.material) ? object.material[0] : object.material);
        }
        // 添加Cylinder物体的物理特性
        if (object.name.startsWith('圆柱') && object instanceof THREE.Mesh) {
            object.visible = false;
            const box = new THREE.Box3().setFromObject(object);
            const size = box.getSize(new THREE.Vector3());
            const center = box.getCenter(new THREE.Vector3());

            // 创建圆柱体的物理对象，降低质量使其更容易破碎
            const cylinderMass = 50; // 显著降低质量
            const cylinderHeight = size.y;
            const cylinderRadius = Math.max(size.x, size.z) / 2;
            pos.copy(center);
            quat.set(0, 0, 0, 1);

            // 使用createObject创建可破碎的圆柱体，传入true表示是圆柱体
            const cylinderHalfExtents = new THREE.Vector3(cylinderRadius, cylinderHeight / 2, cylinderRadius);
            createObject(cylinderMass, cylinderHalfExtents, pos, quat, Array.isArray(object.material) ? object.material[0] : object.material, true);
        }
    });

    // 创建轨道上的障碍物
    createTrajectoryObstacles();

    // 添加钻头的物理特性
    if (drillBit) {
        const drillBitMesh = drillBit as THREE.Mesh;
        const drillBitPos = new THREE.Vector3();
        drillBit.getWorldPosition(drillBitPos); // 获取钻头的世界位置
        const drillBitQuat = new THREE.Quaternion();
        drillBit.getWorldQuaternion(drillBitQuat); // 获取钻头的世界旋转

        // 增加钻头的质量和碰撞体积
        const drillBitPhysics = createCylinderWithPhysics(
            0.2, // 增加半径
            3,   // 高度
            150000,  // 增加质量
            drillBitPos,
            drillBitQuat,
            Array.isArray(drillBitMesh.material) ? drillBitMesh.material[0] : drillBitMesh.material
        );

        // 设置物理对象不可见
        drillBitPhysics.visible = false;

        // 将原始钻头的位置和旋转同步到物理对象
        drillBit.position.copy(drillBitPhysics.position);
        drillBit.quaternion.copy(drillBitPhysics.quaternion);

        // 获取钻头的物理体
        drillBitPhysicsBody = drillBitPhysics.userData.physicsBody;

        // 初始化时禁用重力
        if (drillBitPhysicsBody) {
            drillBitPhysicsBody.setGravity(new AmmoLib.btVector3(0, 0, 0));
            // 增加钻头的摩擦力和恢复系数
            drillBitPhysicsBody.setFriction(1.0);
            drillBitPhysicsBody.setRestitution(0.2);
        }
    }
}

/**
 * 创建圆柱体物理对象
 * @param radius 半径
 * @param height 高度
 * @param mass 质量
 * @param pos 位置
 * @param quat 四元数
 * @param material 材质
 */
function createCylinderWithPhysics(radius: number, height: number, mass: number, pos: THREE.Vector3, quat: THREE.Quaternion, material: THREE.Material) {
    // 在开发模式下使用线框材质
    const displayMaterial = WIREFRAME_MODE ? wireMaterial : material;
    const object = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, height, 32), displayMaterial);

    // 如果是线框模式，保存原始材质
    if (WIREFRAME_MODE) {
        object.userData.originalMaterial = material;
    }

    const shape = new AmmoLib.btCylinderShape(new AmmoLib.btVector3(radius, height * 0.5, radius));
    shape.setMargin(margin);

    const body = createRigidBody(object, shape, mass, pos, quat, null, null);

    // 增加钻头的碰撞检测精度
    if (mass > 10000) { // 假设这是钻头（基于质量判断）
        body.setCcdMotionThreshold(1);
        body.setCcdSweptSphereRadius(radius * 0.8);
    }

    return object;
}


// 从可破碎物体创建碎片
function createDebrisFromBreakableObject(object: THREE.Mesh) {
    // 设置阴影
    object.castShadow = true;
    // 设置阴影接收
    object.receiveShadow = true;

    // 创建凸包物理形状
    const shape = createConvexHullPhysicsShape(new Float32Array(object.geometry.attributes.position.array));
    shape.setMargin(margin);

    const body = createRigidBody(object, shape, object.userData.mass, null, null, object.userData.velocity, object.userData.angularVelocity);

    // 只在碎片对象中设置指向three对象的指针
    const btVecUserData = new AmmoLib.btVector3(0, 0, 0);
    btVecUserData.threeObject = object;
    body.setUserPointer(btVecUserData);

    // 为圆柱体碎片设置特殊属性
    if (object.userData.cylinderCollision) {
        body.setFriction(0.8);
        body.setRestitution(0.3);
        body.setGravity(new AmmoLib.btVector3(0, 0, 0));
        body.setActivationState(4);
    }
}

/**
 * 创建碎片的函数
 * @param {THREE.Mesh} object - 要创建碎片的网格对象
 */
function createDebrisWithAutoCleanup(object: THREE.Mesh) {
    // 在线框模式下修改碎片材质
    if (WIREFRAME_MODE) {
        // 创建一个新的线框材质，颜色略有不同以区分不同的碎片
        const debrisWireMaterial = wireMaterial.clone();
        // 随机微调颜色
        (debrisWireMaterial as THREE.MeshBasicMaterial).color.offsetHSL(0, 0, Math.random() * 0.3 - 0.15);

        if (Array.isArray(object.material)) {
            // 保存原始材质
            object.userData.originalMaterials = object.material.slice();
            object.material = Array(object.material.length).fill(debrisWireMaterial);
        } else {
            // 保存原始材质
            object.userData.originalMaterial = object.material;
            object.material = debrisWireMaterial;
        }
    } else {
        // 原有的克隆材质逻辑
        if (Array.isArray(object.material)) {
            const newMaterials = object.material.map(mat => {
                const newMat = mat.clone();
                if (newMat instanceof THREE.MeshStandardMaterial) {
                    // 克隆纹理
                    if (newMat.map) newMat.map = newMat.map.clone();
                    if (newMat.normalMap) newMat.normalMap = newMat.normalMap.clone();
                }
                newMat.transparent = true;
                newMat.opacity = 1.0;
                return newMat;
            });
            object.material = newMaterials;
        } else {
            const originalMat = object.material;
            const newMat = originalMat.clone();
            if (newMat instanceof THREE.MeshStandardMaterial) {
                // 克隆纹理
                if (newMat.map) newMat.map = newMat.map.clone();
                if (newMat.normalMap) newMat.normalMap = newMat.normalMap.clone();
            }
            newMat.transparent = true;
            newMat.opacity = 1.0;
            object.material = newMat;
        }
    }

    // 创建物理碎片
    createDebrisFromBreakableObject(object);

    // 将碎片添加到活动碎片列表中
    activeDebris.push({
        mesh: object,
        creationTime: Date.now(),
        material: object.material,
        originalOpacity: 1.0
    });

    // 在 createDebrisWithAutoCleanup 函数中增加限制
    const MAX_DEBRIS_COUNT = 100;

    if (activeDebris.length >= MAX_DEBRIS_COUNT) {
        const oldestDebris = activeDebris.shift();
        if (oldestDebris) {
            disposeDebris(oldestDebris.mesh);
        }
    }
}

/**
 * 移除碎片
 * @param {THREE.Mesh} object - 要移除的碎片网格对象
 */
function removeDebris(object: THREE.Mesh) {
    scene.remove(object)
    physicsWorld.removeRigidBody(object.userData.physicsBody);

    // 释放几何体
    if (object.geometry) {
        object.geometry.dispose();
    }

    // 释放材质
    if (object.material instanceof THREE.Material) {
        if (object.material instanceof THREE.MeshStandardMaterial || object.material instanceof THREE.MeshPhongMaterial) {
            if (object.material.map) object.material.map.dispose();
        }
        object.material.dispose();
    } else if (Array.isArray(object.material)) {
        object.material.forEach(material => {
            if (material instanceof THREE.MeshStandardMaterial || material instanceof THREE.MeshPhongMaterial) {
                if (material.map) material.map.dispose();
            }
            material.dispose();
        });
    }
}

/**
 * 创建凸包物理形状
 * @param coords 顶点坐标
 */
function createConvexHullPhysicsShape(coords: Float32Array) {
    const shape = new AmmoLib.btConvexHullShape(); // 创建凸包形状

    for (let i = 0, il = coords.length; i < il; i += 3) {
        tempBtVec3_1.setValue(coords[i], coords[i + 1], coords[i + 2]); // 设置顶点坐标
        const lastOne = (i >= (il - 3)); // 判断是否是最后一个顶点
        shape.addPoint(tempBtVec3_1, lastOne); // 添加顶点到凸包形状
    }

    return shape;
}

/**
 * 创建物理刚体并添加到物理世界
 * @description 根据给定的参数创建刚体，配置相关物理属性，并将其添加到物理世界与场景中
 * 
 * @param {THREE.Mesh} object - Three.js 网格对象
 * @param {Ammo.btCollisionShape} physicsShape - 物理碰撞形状
 * @param {number} mass - 质量（0表示静态物体）
 * @param {THREE.Vector3 | null} pos - 位置，如果为null则使用对象当前位置
 * @param {THREE.Quaternion | null} quat - 旋转四元数，如果为null则使用对象当前旋转
 * @param {THREE.Vector3 | null} vel - 初始线性速度
 * @param {THREE.Vector3 | null} angVel - 初始角速度
 * @returns {Ammo.btRigidBody} 创建的刚体对象
 */
function createRigidBody(
    object: THREE.Mesh,
    physicsShape: Ammo.btCollisionShape,
    mass: number,
    pos: THREE.Vector3 | null,
    quat: THREE.Quaternion | null,
    vel: THREE.Vector3 | null,
    angVel: THREE.Vector3 | null
): Ammo.btRigidBody {
    // 设置位置和旋转
    if (pos) {
        object.position.copy(pos);
    } else {
        pos = object.position;
    }

    if (quat) {
        object.quaternion.copy(quat);
    } else {
        quat = object.quaternion;
    }

    // 创建变换对象
    const transform = new AmmoLib.btTransform();
    transform.setIdentity(); // 设置为单位变换
    transform.setOrigin(new AmmoLib.btVector3(pos.x, pos.y, pos.z)); // 设置位置
    transform.setRotation(new AmmoLib.btQuaternion(quat.x, quat.y, quat.z, quat.w)); // 设置旋转

    // 创建运动状态
    const motionState = new AmmoLib.btDefaultMotionState(transform);

    // 计算惯性
    const localInertia = new AmmoLib.btVector3(0, 0, 0);
    if (mass > 0) {
        physicsShape.calculateLocalInertia(mass, localInertia);
    }

    // 创建刚体构造信息
    const rbInfo = new AmmoLib.btRigidBodyConstructionInfo(
        mass,
        motionState,
        physicsShape,
        localInertia
    );

    // 创建刚体
    const body = new AmmoLib.btRigidBody(rbInfo);

    // 设置摩擦系数（根据物体类型调整）
    body.setFriction(object.userData.cylinderCollision ? 0.8 : 0.5);

    // 设置初始速度
    if (vel) {
        body.setLinearVelocity(new AmmoLib.btVector3(vel.x, vel.y, vel.z));
    }

    // 设置初始角速度
    if (angVel) {
        body.setAngularVelocity(new AmmoLib.btVector3(angVel.x, angVel.y, angVel.z));
    }

    // 将物理体关联到对象的用户数据
    object.userData.physicsBody = body;

    // 添加到场景
    scene.add(object);

    // 添加到刚体列表（仅动态物体）
    if (mass > 0) {
        rigidBodies.push(object);
        // 禁用刚体休眠
        body.setActivationState(4);
    }

    // 添加到物理世界
    physicsWorld.addRigidBody(body);

    return body;
}


/**
 * @type {number}
 * @description 上次消息时间
 */
let lastMessageTime = 0;
/**
 * @type {number}
 * @description 消息冷却时间(毫秒)
 */
const MESSAGE_COOLDOWN = 2000;
/**
 * @type {number}
 * @description 碰撞计数器
 */
let collisionCount = 0;

/**
 * 更新物理世界
 * @param {number} deltaTime - 时间步长
 * @param {Ref<number>} currentSpeed - 当前速度引用
 * @param {Ref<number>} drillDepth - 钻井深度引用
 */
export function updatePhysics(deltaTime: number, currentSpeed: Ref<number>, drillDepth: Ref<number>) {
    if (!physicsWorld) {
        return;
    }

    // 处理碎片渐隐效果
    const currentTime = Date.now();
    // 碎片移除列表
    const debrisToRemove: DebrisInfo[] = [];

    for (const debris of activeDebris) {
        const elapsedTime = currentTime - debris.creationTime;

        if (elapsedTime >= FADE_DURATION) {
            // 时间到，移除碎片
            debrisToRemove.push(debris);
        } else {
            // 计算当前透明度
            const fadeProgress = elapsedTime / FADE_DURATION;
            const currentOpacity = debris.originalOpacity * (1 - fadeProgress);

            // 更新材质透明度
            if (Array.isArray(debris.material)) {
                debris.material.forEach(material => {
                    material.opacity = currentOpacity;
                });
            } else {
                debris.material.opacity = currentOpacity;
            }
        }
    }

    // 移除完全透明的碎片
    for (const debris of debrisToRemove) {
        removeDebris(debris.mesh);
        const index = activeDebris.indexOf(debris);
        if (index > -1) {
            activeDebris.splice(index, 1);
        }
    }

    // 推进物理世界模拟
    physicsWorld.stepSimulation(deltaTime, 10);

    // 更新刚体
    for (let i = 0, il = rigidBodies.length; i < il; i++) {
        const objThree = rigidBodies[i];
        const objPhys = objThree.userData.physicsBody;
        const ms = objPhys.getMotionState();

        if (ms) {
            ms.getWorldTransform(transformAux1); // 获取物理对象的世界变换
            const p = transformAux1.getOrigin(); // 获取位置
            const q = transformAux1.getRotation(); // 获取旋转
            objThree.position.set(p.x(), p.y(), p.z()); // 更新 Three.js 物体的位置
            objThree.quaternion.set(q.x(), q.y(), q.z(), q.w()); // 更新 Three.js 物体的旋转

        }
    }

    // 处理碰撞
    for (let i = 0, il = dispatcher.getNumManifolds(); i < il; i++) {
        const contactManifold = dispatcher.getManifoldByIndexInternal(i);
        const rb0 = AmmoLib.castObject(contactManifold.getBody0(), AmmoLib.btRigidBody);
        const rb1 = AmmoLib.castObject(contactManifold.getBody1(), AmmoLib.btRigidBody);

        const threeObject0 = AmmoLib.castObject(rb0.getUserPointer(), AmmoLib.btVector3).threeObject;
        const threeObject1 = AmmoLib.castObject(rb1.getUserPointer(), AmmoLib.btVector3).threeObject;

        // 如果两个物体都不存在，跳过
        if (!threeObject0 && !threeObject1) {
            continue;
        }

        // 检查是否有一个物体是钻头
        const isDrillCollision = (rb0 === drillBitPhysicsBody || rb1 === drillBitPhysicsBody);

        const userData0 = threeObject0 ? threeObject0.userData : null;
        const userData1 = threeObject1 ? threeObject1.userData : null;

        // 检查是否有一个物体是可破碎的
        const breakable0 = userData0 ? userData0.breakable : false;
        const breakable1 = userData1 ? userData1.breakable : false;

        // 检查是否有一个物体已经碰撞
        const collided0 = userData0 ? userData0.collided : false;
        const collided1 = userData1 ? userData1.collided : false;

        if ((!breakable0 && !breakable1) || (collided0 && collided1)) {
            continue;
        }

        // 根据物体类型调整破碎阈值
        let fractureImpulse = 150;
        if (isDrillCollision) {
            // 如果是圆柱体，使用更低的破碎阈值
            if ((userData0 && userData0.cylinderCollision) || (userData1 && userData1.cylinderCollision)) {
                fractureImpulse = 10;
            } else {
                fractureImpulse = 30;
            }
        }

        // 是否接触
        let contact = false;
        // 最大冲量
        let maxImpulse = 0;
        // 遍历所有接触点
        for (let j = 0, jl = contactManifold.getNumContacts(); j < jl; j++) {
            const contactPoint = contactManifold.getContactPoint(j);

            // 如果接触点距离小于0，则表示接触
            if (contactPoint.getDistance() < 0) {
                contact = true;
                // 调整冲量计算
                let impulse = contactPoint.getAppliedImpulse();
                if (isDrillCollision) {
                    // 对圆柱体增加额外的冲量
                    if ((userData0 && userData0.cylinderCollision) || (userData1 && userData1.cylinderCollision)) {
                        impulse *= 5000;
                    } else {
                        impulse *= 15;
                    }
                }

                if (impulse > maxImpulse) {
                    maxImpulse = impulse;
                    // 获取接触点位置和法线
                    const pos = contactPoint.get_m_positionWorldOnB();
                    const normal = contactPoint.get_m_normalWorldOnB();
                    impactPoint.set(pos.x(), pos.y(), pos.z());
                    impactNormal.set(normal.x(), normal.y(), normal.z());
                }
                break;
            }
        }

        // 如果没有接触点，跳过
        if (!contact) continue;

        // 如果是钻头碰撞，播放音效并显示提示
        if (isDrillCollision && contact) {
            fragmentationSound.currentTime = 0;
            fragmentationSound.play();

            // 检查是否可以显示新消息
            const currentTime = Date.now();
            if (currentTime - lastMessageTime > MESSAGE_COOLDOWN) {
                collisionCount++;

                // 根据钻井状态选择不同的消息
                if (!isDrilling.value) {
                    // 上提时的行为 - 与下钻类似
                    const isEvenCollision = collisionCount % 2 === 0;

                    // 降低速度
                    if (!isPullUpSpeedReduced) {
                        isPullUpSpeedReduced = true;
                        originalPullUpSpeed = currentSpeed.value;
                        // 根据碰撞次数决定速度降低程度
                        const reductionFactor = isEvenCollision ? 0.6 : 0.8; // 偶数次碰撞降低更多
                        const reducedSpeed = originalPullUpSpeed * reductionFactor;
                        currentSpeed.value = reducedSpeed;

                        // 清除之前的定时器
                        if (pullUpSpeedRecoveryTimeout) {
                            clearTimeout(pullUpSpeedRecoveryTimeout);
                        }

                        // 设置定时器恢复速度
                        pullUpSpeedRecoveryTimeout = window.setTimeout(() => {
                            if (isPullUpSpeedReduced) {
                                console.log('恢复上提速度:', originalPullUpSpeed);
                                currentSpeed.value = originalPullUpSpeed;
                                isPullUpSpeedReduced = false;
                                message.success('上提速度已恢复正常');
                            }
                        }, PULLUP_SPEED_RECOVERY_DELAY);

                        // 显示通知
                        const notificationMessage = isEvenCollision ?
                            '检测到严重卡阻，上提速度已大幅降低' :
                            '检测到轻微遇阻，上提速度已适度降低';

                        notification.warning({
                            message: `上提警告 - ${new Date().toLocaleTimeString()}`,
                            // description: `${notificationMessage} ${(Math.abs(reducedSpeed) * 3600).toFixed(2)} m/h`,
                            description: `${notificationMessage}`,
                            duration: 4,
                            style: {
                                top: '350px',
                                fontWeight: 'bold',
                                backgroundColor: '#f39c12',
                                color: '#ffffff',
                                width: '350px'
                            },
                            class: 'custom-notification-message'
                        });
                    }
                } else {
                    // 在开始下钻时重置上提相关状态
                    isPullUpSpeedReduced = false;
                    if (pullUpSpeedRecoveryTimeout) {
                        clearTimeout(pullUpSpeedRecoveryTimeout);
                        pullUpSpeedRecoveryTimeout = null;
                    }

                    // 下钻时的行为
                    // 根据碰撞次数决定行为
                    const isEvenCollision = collisionCount % 2 === 0;

                    // 降低速度
                    if (!isSpeedReduced) {
                        isSpeedReduced = true;
                        originalSpeed = currentSpeed.value;
                        // 根据碰撞次数决定速度降低程度
                        const reductionFactor = isEvenCollision ? 0.3 : 0.5; // 偶数次碰撞降低更多
                        const reducedSpeed = originalSpeed * reductionFactor;
                        currentSpeed.value = reducedSpeed;

                        // 清除之前的定时器
                        if (speedRecoveryTimeout) {
                            clearTimeout(speedRecoveryTimeout);
                        }

                        // 设置定时器恢复速度
                        speedRecoveryTimeout = window.setTimeout(() => {
                            if (isSpeedReduced) {
                                console.log('恢复速度:', originalSpeed);
                                currentSpeed.value = originalSpeed;
                                isSpeedReduced = false;
                                message.success('钻井速度已恢复正常');
                            }
                        }, SPEED_RECOVERY_DELAY);

                        // 显示通知
                        const notificationMessage = isEvenCollision ?
                            '检测到严重卡阻，钻进速度已大幅降低' :
                            '检测到轻微遇阻，钻进速度已适度降低';

                        notification.error({
                            message: `下放警告 - ${new Date().toLocaleTimeString()}`,
                            // description: `${notificationMessage} ${(reducedSpeed * 3600).toFixed(2)} m/h`,
                            description: `${notificationMessage} `,
                            duration: 3,
                            style: {
                                top: '350px',
                                fontWeight: 'bold',
                                backgroundColor: '#e74c3c',
                                color: '#ffffff',
                                width: '350px'
                            },
                            class: 'custom-notification-message'
                        });
                    }
                }

                lastMessageTime = currentTime;
            }

            const now = Date.now();
            if (now - lastCollisionRecordTime > 2000) {
                // 只在距离上次记录超过1秒时才记录
                const warningStore = useCollisionWarningStore();
                warningStore.addWarning({
                    id: Date.now(),
                    time: new Date().toLocaleTimeString(),
                    type: isDrilling.value ? '遇阻' : '遇卡',
                    message: isDrilling.value ? '检测到仪器遇阻' : '检测到仪器遇卡',
                    depth: drillDepth.value,
                    // 可选：depth: 当前深度
                });
                lastCollisionRecordTime = now;
            }
        }

        // 处理第一个物体的分裂
        if (contact && breakable0 && !collided0 && maxImpulse > fractureImpulse) {
            const fragmentCount = userData0.cylinderCollision ? 1 : 1;
            const debris = convexBreaker.subdivideByImpact(threeObject0, impactPoint, impactNormal, fragmentCount, 2, 1.5);

            const numObjects = debris.length;
            for (let j = 0; j < numObjects; j++) {
                const vel = rb0.getLinearVelocity();
                const angVel = rb0.getAngularVelocity();
                const fragment = debris[j] as THREE.Mesh;

                // 为每个碎片创建新的材质实例
                if (threeObject0 instanceof THREE.Mesh) {
                    if (Array.isArray(threeObject0.material)) {
                        fragment.material = threeObject0.material.map(mat => mat.clone());
                    } else {
                        fragment.material = threeObject0.material.clone();
                    }
                }

                const velocityMultiplier = userData0.cylinderCollision ? 2.0 : 1.5;
                fragment.userData.velocity.set(
                    vel.x() * velocityMultiplier,
                    vel.y() * velocityMultiplier,
                    vel.z() * velocityMultiplier
                );
                fragment.userData.angularVelocity.set(
                    angVel.x() * velocityMultiplier,
                    angVel.y() * velocityMultiplier,
                    angVel.z() * velocityMultiplier
                );

                // 使用新的函数创建碎片
                createDebrisWithAutoCleanup(fragment);
            }

            objectsToRemove[numObjectsToRemove++] = threeObject0;
            userData0.collided = true;
        } else if (contact && userData0 && userData0.cylinderCollision && !userData0.collided) {
            // 如果是圆柱体且发生碰撞但未破碎，启用重力
            if (rb0) {
                rb0.setGravity(new AmmoLib.btVector3(0, -gravityConstant, 0));
                rb0.activate(true);
                userData0.collided = true;
            }
        }

        // 处理第二个物体的分裂
        if (contact && breakable1 && !collided1 && maxImpulse > fractureImpulse) {
            const fragmentCount = userData1.cylinderCollision ? 1 : 1;
            const debris = convexBreaker.subdivideByImpact(threeObject1, impactPoint, impactNormal, fragmentCount, 2, 1.5);

            const numObjects = debris.length;
            for (let j = 0; j < numObjects; j++) {
                const vel = rb1.getLinearVelocity();
                const angVel = rb1.getAngularVelocity();
                const fragment = debris[j] as THREE.Mesh;
                const velocityMultiplier = userData1.cylinderCollision ? 2.0 : 1.5;
                fragment.userData.velocity.set(
                    vel.x() * velocityMultiplier,
                    vel.y() * velocityMultiplier,
                    vel.z() * velocityMultiplier
                );
                fragment.userData.angularVelocity.set(
                    angVel.x() * velocityMultiplier,
                    angVel.y() * velocityMultiplier,
                    angVel.z() * velocityMultiplier
                );

                // 使用新的函数创建碎片
                createDebrisWithAutoCleanup(fragment);

                if (fragment.userData.physicsBody) {
                    fragment.userData.physicsBody.setGravity(new AmmoLib.btVector3(0, -gravityConstant, 0));
                    fragment.userData.physicsBody.activate(true);
                }
            }

            objectsToRemove[numObjectsToRemove++] = threeObject1;
            userData1.collided = true;
        } else if (contact && userData1 && userData1.cylinderCollision && !userData1.collided) {
            // 如果是圆柱体且发生碰撞但未破碎，启用重力
            if (rb1) {
                rb1.setGravity(new AmmoLib.btVector3(0, -gravityConstant, 0));
                rb1.activate(true);
                userData1.collided = true;
            }
        }
    }

    // 移除标记的物体
    for (let i = 0; i < numObjectsToRemove; i++) {
        if (objectsToRemove[i]) {
            removeDebris(objectsToRemove[i] as THREE.Mesh);
        }
    }
    numObjectsToRemove = 0;
}

/**
 * 更新钻头速度
 * @param {number} speed - 速度
 */
export function updateDrillBitVelocity(speed: number) {
    if (drillBitPhysicsBody) {
        // 根据当前操作状态选择适当的速度降低因子
        let actualSpeed = speed;
        if (speed > 0 && isSpeedReduced) { // 下钻状态且速度已降低
            actualSpeed = speed * SPEED_REDUCTION_FACTOR;
        } else if (speed < 0 && isPullUpSpeedReduced) { // 上提状态且速度已降低
            actualSpeed = speed * PULLUP_SPEED_REDUCTION_FACTOR;
        }

        const vel = new AmmoLib.btVector3(0, -actualSpeed, 0);
        drillBitPhysicsBody.setLinearVelocity(vel);
        drillBitPhysicsBody.setGravity(new AmmoLib.btVector3(0, 0, 0));

        // 如果速度方向发生变化（从下钻变为上提或从上提变为下钻），重置相关状态
        const currentSpeedSign = Math.sign(speed);

        if (previousSpeedSign !== 0 && previousSpeedSign !== currentSpeedSign) {
            // 如果从下钻切换到上提
            if (previousSpeedSign > 0 && currentSpeedSign < 0) {
                // 重置下钻相关状态
                isSpeedReduced = false;
                if (speedRecoveryTimeout) {
                    clearTimeout(speedRecoveryTimeout);
                    speedRecoveryTimeout = null;
                }
            }
            // 如果从上提切换到下钻
            else if (previousSpeedSign < 0 && currentSpeedSign > 0) {
                // 重置上提相关状态
                isPullUpSpeedReduced = false;
                if (pullUpSpeedRecoveryTimeout) {
                    clearTimeout(pullUpSpeedRecoveryTimeout);
                    pullUpSpeedRecoveryTimeout = null;
                }
            }
        }

        previousSpeedSign = currentSpeedSign;
    }
}

/**
 * 导出用于轨道切换时重新创建障碍物的函数
 * @returns {void}
 */
export function recreateTrajectoryObstacles() {
    if (physicsWorld) {
        createTrajectoryObstacles();
    }
}

/**
 * 释放物理体资源
 * @param {Ammo.btRigidBody} body - 物理刚体
 */
function disposePhysicsBody(body: Ammo.btRigidBody): void {
    if (!body) return;

    // 从物理世界移除
    physicsWorld.removeRigidBody(body);

    // 释放运动状态
    const motionState = body.getMotionState();
    if (motionState) {
        AmmoLib.destroy(motionState);
    }

    // 释放碰撞形状
    const shape = body.getCollisionShape();
    if (shape) {
        AmmoLib.destroy(shape);
    }

    // 释放刚体
    AmmoLib.destroy(body);
}

/**
 * 完整释放碎片资源
 * @param {THREE.Mesh} debris - 碎片对象
 */
function disposeDebris(debris: THREE.Mesh): void {
    if (!debris) return;

    // 从场景移除
    scene.remove(debris);

    // 释放物理资源
    if (debris.userData.physicsBody) {
        disposePhysicsBody(debris.userData.physicsBody);
    }

    // 释放几何体
    if (debris.geometry) {
        debris.geometry.dispose();
    }

    // 完整释放材质和纹理
    if (Array.isArray(debris.material)) {
        debris.material.forEach((mat: THREE.Material) => {
            disposeMaterial(mat);
        });
    } else if (debris.material) {
        disposeMaterial(debris.material);
    }
}

/**
 * 释放材质资源
 * @param {THREE.Material} material - 材质
 */
function disposeMaterial(material: THREE.Material): void {
    // 处理常见的材质类型和纹理
    if (material instanceof THREE.MeshStandardMaterial) {
        if (material.map) material.map.dispose();
        if (material.normalMap) material.normalMap.dispose();
        if (material.roughnessMap) material.roughnessMap.dispose();
        if (material.metalnessMap) material.metalnessMap.dispose();
        if (material.emissiveMap) material.emissiveMap.dispose();
    } else if (material instanceof THREE.MeshPhongMaterial) {
        if (material.map) material.map.dispose();
        if (material.normalMap) material.normalMap.dispose();
        if (material.specularMap) material.specularMap.dispose();
    }

    material.dispose();
}


/**
 * 导出资源清理函数
 * @returns {void}
 */
export function disposeCollisionResources(): void {
    // 清理所有活动碎片
    while (activeDebris.length > 0) {
        const debris = activeDebris.pop();
        if (debris) {
            disposeDebris(debris.mesh);
        }
    }

    // 清理所有刚体
    rigidBodies.forEach(body => {
        disposeDebris(body);
    });
    rigidBodies.length = 0;

    // 清理纹理
    if (obstacleTexture) {
        obstacleTexture.dispose();
    }

    // 清理音频
    if (fragmentationSound) {
        fragmentationSound.pause();
        fragmentationSound.src = '';
    }

    // 清理物理世界资源
    if (physicsWorld) {
        // 确保所有调度器和碰撞配置被正确销毁
        if (dispatcher) {
            AmmoLib.destroy(dispatcher);
            dispatcher = null as unknown as Ammo.btCollisionDispatcher;
        }

        if (collisionConfiguration) {
            AmmoLib.destroy(collisionConfiguration);
            collisionConfiguration = null as unknown as Ammo.btCollisionConfiguration;
        }

        if (broadphase) {
            AmmoLib.destroy(broadphase);
            broadphase = null as unknown as Ammo.btBroadphaseInterface;
        }

        if (solver) {
            AmmoLib.destroy(solver);
            solver = null as unknown as Ammo.btConstraintSolver;
        }

        if (transformAux1) {
            AmmoLib.destroy(transformAux1);
            transformAux1 = null as unknown as Ammo.btTransform;
        }

        if (tempBtVec3_1) {
            AmmoLib.destroy(tempBtVec3_1);
            tempBtVec3_1 = null as unknown as Ammo.btVector3;
        }

        AmmoLib.destroy(physicsWorld);
        physicsWorld = null as unknown as Ammo.btDiscreteDynamicsWorld;
    }
}

/**
 * 切换线框模式显示
 * @description 切换所有物理对象的线框显示模式，用于开发和调试目的
 * 
 * @param {boolean} [enable] - 是否启用线框模式，如果不提供则切换当前状态
 * @returns {boolean} 切换后的线框模式状态
 */
export function toggleWireframeMode(enable?: boolean): boolean {
    // 如果提供了具体值就使用，否则切换当前状态
    if (enable !== undefined) {
        WIREFRAME_MODE = enable;
    } else {
        WIREFRAME_MODE = !WIREFRAME_MODE;
    }

    // 应用线框模式到所有现有的物理对象
    applyWireframeMode();

    return WIREFRAME_MODE;
}

/**
 * 应用线框模式到所有现有的物理对象
 * @description 根据当前的线框模式状态，更新所有刚体、障碍物和碎片的材质
 */
function applyWireframeMode(): void {
    // 更新刚体材质
    updateObjectsWireframeMode(rigidBodies);

    // 更新障碍物材质
    updateObjectsWireframeMode(trajectoryObstacles);

    // 更新碎片材质
    activeDebris.forEach(debris => {
        updateObjectWireframeMode(debris.mesh, true);
        // 更新activeDebris中的材质引用
        debris.material = debris.mesh.material;
    });
}

/**
 * 更新物体数组的线框模式
 * @param {THREE.Mesh[]} objects - 需要更新的物体数组
 */
function updateObjectsWireframeMode(objects: THREE.Mesh[]): void {
    objects.forEach(object => {
        updateObjectWireframeMode(object);
    });
}

/**
 * 更新单个物体的线框模式
 * @param {THREE.Mesh} object - 需要更新的物体
 * @param {boolean} [isDebris=false] - 是否为碎片物体
 */
function updateObjectWireframeMode(object: THREE.Mesh, isDebris: boolean = false): void {
    if (WIREFRAME_MODE) {
        // 保存原材质并使用线框材质
        if (!object.userData.originalMaterial && !object.userData.originalMaterials) {
            let wireframeMaterialToUse = wireMaterial;

            // 为碎片创建略微不同的线框材质以区分
            if (isDebris) {
                wireframeMaterialToUse = wireMaterial.clone();
                (wireframeMaterialToUse as THREE.MeshBasicMaterial).color.offsetHSL(0, 0, Math.random() * 0.3 - 0.15);
            }

            if (Array.isArray(object.material)) {
                object.userData.originalMaterials = object.material.slice();
                object.material = Array(object.material.length).fill(wireframeMaterialToUse);
            } else {
                object.userData.originalMaterial = object.material;
                object.material = wireframeMaterialToUse;
            }
        }
    } else {
        // 恢复原材质
        if (object.userData.originalMaterials) {
            object.material = object.userData.originalMaterials;
            delete object.userData.originalMaterials;
        } else if (object.userData.originalMaterial) {
            object.material = object.userData.originalMaterial;
            delete object.userData.originalMaterial;
        }
    }
}
